package com.dbumama.market.web.mobile.trans.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dbumama.market.model.*;
import com.dbumama.market.service.api.area.AreaService;
import com.dbumama.market.service.api.cart.CartService;
import com.dbumama.market.service.api.receiver.BuyerReceiverSubmitParamDto;
import com.dbumama.market.service.api.receiver.ReceiverService;
import com.dbumama.market.service.api.trans.TransService;
import com.dbumama.market.service.api.unionfit.UnionFitService;
import com.dbumama.market.service.api.user.UserService;
import com.dbumama.market.service.api.verified.VerifiedService;
import com.dbumama.market.web.core.annotation.RouteBind;
import com.dbumama.market.web.core.controller.BaseMobileController;
import com.dbumama.market.web.core.plugin.spring.Inject.BY_NAME;
import com.dbumama.market.web.core.utils.AjaxResult;
import com.dbumama.market.web.core.utils.CertificateUtils;
import com.dbumama.market.web.core.utils.SMSUtils;
import com.dbumama.market.web.core.utils.StringUtils;
import com.dbumama.market.web.mobile.verified.controller.VerifiedController;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.ehcache.CacheKit;
import org.apache.commons.codec.binary.Base64;

import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.*;

@RouteBind(path = "trans")
public class TransController extends BaseMobileController {

    @BY_NAME
    TransService transService;
    @BY_NAME
    VerifiedService verifiedService;
    @BY_NAME
    UnionFitService unionFitService;
    @BY_NAME
    UserService userService;

    AjaxResult result = new AjaxResult();

    public void index() {
        render("/trans/index.html");
    }

    public void getAllOrders(){
        List<TransOrder> list = transService.getOrdersByBuyerId(getBuyerId());
        setAttr("orderList",list);
        setAttr("count",list.size());
        render("/trans/transOrder.html");
    }


    public void collectingSilver() {
        render("/trans/tpl_pay.html");
    }

    public void createOrder() {
        String transId = transService.createOrder(getBuyerId(), getPara("amt"));
        Map resp = new HashMap();
        resp.put("trans_id", transId);
        rendSuccessJson(resp);
    }

    //http://localhost:8080/trans/payFrom?trans_id=TX180726000009
    public void payFrom() {
        String trans_id = getPara("trans_id");
        TransOrder transOrder = transService.getOrder(trans_id);
        if (transOrder == null) {
            setAttr("error", "找不到订单");
            render("/trans/st_error.html");
            return;
        }
        setAttr("transOrder", transOrder);
        render("/trans/qrcode_trans.html");
    }

    public void toSettlePan(){
        List<BuyerSettleInfo> settleInfos = transService.findSettleList(getBuyerId());
        VerifiedInfo verifiedInfo = verifiedService.findByBuyerId(getBuyerId());
        if(settleInfos.size()==0){
            setAttr("name",verifiedInfo.getName());
            render("/trans/bindSettlePan.html");
            return;
        }else{
            BuyerSettleInfo settleInfo = settleInfos.get(0);
            setAttr("name",verifiedInfo.getName());
            setAttr("bankName",settleInfo.getBankName());
            setAttr("cardNo",settleInfo.getCardNo());
            setAttr("settlePhone",settleInfo.getSettlePhone());
            render("/trans/settlePanInfo.html");
        }
    }

    public void toModify(){
        render("/trans/bindSettlePan.html");
    }

    public void bindSettlePan(){
        try{
            String bankName = getPara("bankName");
            String cardNo = getPara("cardNo");
            String settlePhone = getPara("settlePhone");
            String frontUrly = getPara("frontUrly");
            //校验卡号是否为借记卡
            //检测是否为借记卡
            UnionFit guft = new VerifiedController().checkCardBin(cardNo,"1");
            if(null == guft){
                result.addError("请上传借记卡或储蓄卡正面照片");
                renderJson(result);
                return;
            }
            //查重
            BuyerSettleInfo settleInfo = transService.findByCardNo(cardNo);
            if(settleInfo != null){
                result.addError("该银行卡已被使用");
                renderJson(result);
                return;
            }
            String cnaps_code = "";
            String bankBranch = "";
            if(!StringUtils.isEmpty(guft.getStr("ISSNAM"))){
                bankName = guft.getStr("ISSNAM");//设置银行卡所属银行
                cnaps_code = guft.getStr("ISSNO");
                bankBranch = guft.getStr("CRDNAM");
            }
            HashMap<String,String> bankInfo = new HashMap<String,String>();
            bankInfo.put("cardNo", cardNo);
            bankInfo.put("bankCode", cnaps_code);
            bankInfo.put("bankName", bankName);
            bankInfo.put("bankBranch",bankBranch);
            bankInfo.put("settlePhone",settlePhone);
            bankInfo.put("cardImg",frontUrly);
            setSessionAttr("bankInfo", bankInfo);
            String code = "123456";
            //String code = SMSUtils.sendSMSCode(settlePhone,2);
            if(code == null){
                result.addError("短信验证码发送失败");
                renderJson(result);
                return;
            }
            //保存发送短信记录
            SmsCode smsCode = new SmsCode();
            smsCode.setPhone(settlePhone);
            smsCode.setCode(code);
            smsCode.setType("2");
            smsCode.setCreated(new Date());
            smsCode.setUpdated(new Date());
            boolean flag = smsCode.save();
            log.info("-----------------------save sms_code result:["+flag+"]----------------------------");
            CacheKit.put("bindCardCode", settlePhone, code);
            result.success("验证码发送成功");
            renderJson(result);
        }catch (Exception e){
            log.error("bind settle_pan error:",e);
            result.addError("系统繁忙，请稍后再试！");
            renderJson(result);
            return;
        }
    }

    public void toCode(){
        render("/trans/sendCode.html");
    }

    public void confirmBind(){
        try{
            String verifyCode = getPara("verifyCode");
            HashMap<String,String> bankInfo = getSessionAttr("bankInfo");
            String cardNo = bankInfo.get("cardNo");
            String bankCode = bankInfo.get("bankCode");
            String bankName = bankInfo.get("bankName");
            String bankBranch = bankInfo.get("bankBranch");
            String settlePhone = bankInfo.get("settlePhone");
            String cardImg = bankInfo.get("cardImg");

            //手机验证码验证
            String code = CacheKit.get("bindCardCode", settlePhone);
            if(!verifyCode.equals(code)){
                log.debug("----------------------settlePhone:["+settlePhone+"] sms_code is incorrect----------------------");
                result.addError("验证码错误！");
                renderJson(result);
                return;
            }
            BuyerUser buyerUser = userService.findById(getBuyerId());
            String oldMchtId = buyerUser.getMchtId();

            String url = "";
            if(StringUtils.isEmpty(oldMchtId)){
                url = "regist";
            }else{
                url = "mchtModify";
            }
            String resp = register(url);

            //商户注册
            //String resp = "{\"sign\":\"GS36/eKV0oT6Kdd5b4J0/X4LAzPqe7QBUQjDwm8St5EfoOOFS3PZFboOhzmDaxL3ip6zZDaBNZUG7uY73UHBRMeeP6dz4gBd430DOn/51wWZ5myxhUliGvjMV70CucO2P9WvqY1dOPE9sXdEXn9bZK5E9hKNgkOSx/Zmcmfkcao=\",\"orgId\":\"A80727274015\",\"respCode\":\"0000\",\"respMsg\":null,\"mchtId\":\"M80727274015\"}";
            removeSessionAttr("bankInfo");
            if(resp == null){
                result.addError("绑卡失败");
                renderJson(result);
                return;
            }
            JSONObject obj =  JSONObject.parseObject(resp);
            String respCode = obj.getString("respCode");
            if(!"0000".equals(respCode)){
                result.addError("绑卡失败");
                renderJson(result);
                return;
            }

            String mchtId = obj.getString("mchtId");
            boolean flag = false;
            if(StringUtils.isEmpty(oldMchtId)){
                //保存数据
                BuyerSettleInfo settleInfo = new BuyerSettleInfo();
                settleInfo.setBuyerId(getBuyerId());
                settleInfo.setBankName(bankName);
                settleInfo.setBankCode(bankCode);
                settleInfo.setBankBranch(bankBranch);
                settleInfo.setCardNo(cardNo);
                settleInfo.setSettlePhone(settlePhone);
                settleInfo.setCardImg(cardImg);
                settleInfo.setCreated(new Date());
                settleInfo.setUpdated(new Date());
                flag = settleInfo.save();
                log.info("------------------------save settle_pan result:["+flag+"]-------------------------");
                BuyerUser user = getBuyerUser();
                user.setMchtId(mchtId);
                flag = user.update();
                log.info("------------------------update buyer_user result:["+flag+"]-------------------------");
            }else{
                BuyerSettleInfo settleInfo = transService.findSettleList(getBuyerId()).get(0);
                settleInfo.setBankName(bankName);
                settleInfo.setBankCode(bankCode);
                settleInfo.setBankBranch(bankBranch);
                settleInfo.setCardNo(cardNo);
                settleInfo.setSettlePhone(settlePhone);
                settleInfo.setCardImg(cardImg);
                settleInfo.setUpdated(new Date());
                flag = settleInfo.update();
                log.info("------------------------update settle_pan result:["+flag+"]-------------------------");
            }
            if(flag){
                result.success("绑定成功！");
            }else{
                result.addError("绑定失败！");
            }
            renderJson(result);
        }catch (Exception e){
            log.error("confirm bind error",e);
            result.addError("系统繁忙，请稍后再试！");
            renderJson(result);
        }
    }

    public String register(String url) throws Exception {
        HashMap<String,String> bankInfo = getSessionAttr("bankInfo");
        String cardNo = bankInfo.get("cardNo");
        String bankName = bankInfo.get("bankName");
        String settlePhone = bankInfo.get("settlePhone");
        VerifiedInfo verifiedInfo = verifiedService.findByBuyerId(getBuyerId());
        BuyerUser buyerUser = userService.findById(getBuyerId());
        Map<String, String> req = new TreeMap();
        req.put("bankName", bankName);
        req.put("settleNum", cardNo);
        req.put("mchtName","mcht_"+verifiedInfo.getName());
        String orderId = transService.createOrderId("order_id");
        req.put("orderId", orderId);
        req.put("regOrgCode", "1096");
        if("mchtModify".equals(url)){
            req.put("mchtId", buyerUser.getMchtId());
        }
        req.put("settleIdNum", verifiedInfo.getIdNum());
        req.put("settleName", verifiedInfo.getName());
        req.put("settlePhone", settlePhone);
        req.put("transChannel", "04");
        req.put("transRate", "0.55");
        req.put("withDrawRate", "2");
        String sign = sign(req);
        req.put("sign", sign);
        System.out.println(url+" resp:" + req);
        String resp = sendPost("http://47.96.160.164:8080/gatewaysite/p/"+url, JSON.toJSONString(req));
        //验签
        if("mchtModify".equals(url)){
            TreeMap<String, String> treeMap = JSON.parseObject(resp, TreeMap.class);
            boolean verify = verify(treeMap);
            log.info("------------------check sign result:["+verify+"]-----------------------");
            if(!verify){
                resp = "";
            }
        }
        System.out.println("register resp:" + resp);
        return resp;
    }


    public static boolean verify(TreeMap<String, String> map) throws Exception {
        InputStream in = new FileInputStream("C:/boqi/key/mcht/boqi.cer");
        PublicKey publicKey = CertificateUtils.getPublicKey(in);
        String signature = map.get("sign") + "";
        map.remove("sign");
        StringBuffer sb = new StringBuffer();
        for (Map.Entry key : map.entrySet()) {
            sb.append(key.getKey() + "=" + key.getValue() + "&");
        }
        String string = sb.substring(0, sb.length() - 1);
        Signature st = Signature.getInstance("SHA1withRSA");
        st.initVerify(publicKey);
        st.update(string.getBytes("UTF-8"));
        boolean result = st.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
        return result;
    }

    private static String privateKeyUrl = "C:/boqi/key/mcht/1096.jks";
    private static String password = "1096@123";
    private static PrivateKey privateKey = null;

    static String sign(Map<String, String> resp) {
        StringBuffer sb = new StringBuffer();
        for (String key : resp.keySet()) {
            if (resp.get(key) != null && !resp.get(key).equals(""))
                sb.append(key + "=" + resp.get(key) + "&");
        }
        String queryString = sb.substring(0, sb.length() - 1);// 构造待签名字符串
        FileInputStream fis = null;
        String sign = null;
        try {
            if (privateKey == null) {
                fis = new FileInputStream(privateKeyUrl);
                privateKey = CertificateUtils.getPrivateKey(fis, null, password);
            }
            Signature signature = Signature.getInstance("SHA1withRSA");
            signature.initSign(privateKey);
            signature.update(queryString.getBytes("UTF-8"));
            sign = Base64.encodeBase64String(signature.sign());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fis != null) {
                try {
                    fis.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return sign;
    }

    public static String sendPost(String url, String json) {
        System.out.println(json);
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("Accept", "application/json");
            conn.setRequestProperty("Content-Type", "application/json");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            OutputStream outputStream = conn.getOutputStream();
            outputStream.write(json.getBytes("UTF-8"));
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(),"UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        System.out.print(result);
        return result;
    }

}
